﻿
using Xacml.Core;
using Xacml.Core.Interfaces;
using System;
using System.Xml;

namespace Xacml.Core.Policy
{
  public class VariableDefinitionElement : XacmlElement
  {
    private string _id;
    private IExpression _expression;

    public string Id
    {
      get
      {
        return this._id;
      }
    }

    public IExpression Expression
    {
      get
      {
        return this._expression;
      }
    }

    public override bool IsReadOnly
    {
      get
      {
        return true;
      }
    }

    public VariableDefinitionElement(string id, IExpression expression, XacmlVersion schemaVersion)
      : base(XacmlSchema.Policy, schemaVersion)
    {
      this._id = id;
      this._expression = expression;
    }

    public VariableDefinitionElement(XmlReader reader, XacmlVersion schemaVersion)
      : base(XacmlSchema.Policy, schemaVersion)
    {
      if (reader.LocalName == "VariableDefinition" && this.ValidateSchema(reader, schemaVersion))
      {
        if (reader.HasAttributes)
        {
          while (reader.MoveToNextAttribute())
          {
            if (reader.LocalName == "VariableId")
              this._id = reader.GetAttribute("VariableId");
          }
          reader.MoveToElement();
        }
        while (reader.Read())
        {
          switch (reader.LocalName)
          {
            case "AttributeSelector":
              this._expression = (IExpression) new AttributeSelectorElement(reader, schemaVersion);
              break;
            case "SubjectAttributeDesignator":
              this._expression = (IExpression) new SubjectAttributeDesignatorElement(reader, schemaVersion);
              break;
            case "ActionAttributeDesignator":
              this._expression = (IExpression) new ActionAttributeDesignatorElement(reader, schemaVersion);
              break;
            case "ResourceAttributeDesignator":
              this._expression = (IExpression) new ResourceAttributeDesignatorElement(reader, schemaVersion);
              break;
            case "EnvironmentAttributeDesignator":
              this._expression = (IExpression) new EnvironmentAttributeDesignatorElement(reader, schemaVersion);
              break;
            case "AttributeValue":
              this._expression = (IExpression) new AttributeValueElementReadWrite(reader, schemaVersion);
              break;
            case "Function":
              this._expression = (IExpression) new FunctionElementReadWrite(reader, schemaVersion);
              break;
            case "Apply":
              this._expression = (IExpression) new ApplyElement(reader, schemaVersion);
              break;
            case "VariableReference":
              this._expression = (IExpression) new VariableReferenceElement(reader, schemaVersion);
              break;
          }
          if (reader.LocalName == "VariableDefinition" && reader.NodeType == XmlNodeType.EndElement)
            break;
        }
      }
      else
        throw new Exception(Resource.ResourceManager[Resource.MessageKey.exc_invalid_node_name, new object[1]
        {
          (object) reader.LocalName
        }]);
    }

    public void WriteDocument(XmlWriter writer)
    {
      writer.WriteStartElement("VariableDefinition");
      writer.WriteAttributeString("VariableId", this._id);
      this._expression.WriteDocument(writer);
      writer.WriteEndElement();
    }
  }
}
